using System;
using System.Text;
using System.Reflection;
using System.Runtime.Serialization;

using Crainiate.Data.Persistence.Providers;

namespace Crainiate.Data.Persistence.Providers.Remoting
{
    //Uses a mechanism to pass remoting contexts to underlying contexts
	[Serializable]
    public class RemoteContext: Context, ISerializable
    {
        //Property variables
        private string _name;
        private RemoteManager _dispatcher; //Contains a remote reference to a dispatcher

        #region Interface

        //Constructor
        public RemoteContext()
        {

        }

        public RemoteContext(RemoteManager dispatcher)
        {
            Dispatcher = dispatcher;
        }

        protected RemoteContext(SerializationInfo info, StreamingContext context)
        {
            _name = info.GetString("Name");
        }

        //Properties
        public virtual string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }

        public virtual RemoteManager Dispatcher
        {
            get
            {
                return _dispatcher;
            }
            set
            {
                _dispatcher = value;
            }
        }

        //Methods
        public override Command CreateCommand()
        {
            if (Dispatcher == null) throw new RemotingProviderException("Command could not be created. Set the Dispatcher property to create a Command.");
            RemoteCommand command = new RemoteCommand(this);
            command.Dispatcher = Dispatcher;
            return command;
        }

        public override Concurrency CreateConcurrency()
        {
            if (Dispatcher == null) throw new RemotingProviderException("Concurrency could not be created. Set the Dispatcher property to create a Concurrency object.");
            return _dispatcher.CreateConcurrency(this);
        }

        public override Formatter CreateFormatter()
        {
            throw new RemotingProviderException("Formatter could not be created remotely.");
        }

        public override IPersistable CreatePersistable(Type type)
        {
            if (Dispatcher == null) throw new RemotingProviderException("Persistable could not be created. Set the Dispatcher property to create a Persistable object.");
            return _dispatcher.CreatePersistable(type, this);
        }

        public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("Name", _name);
        }

		#endregion

        #region Overrides

        public override int GetHashCode()
        {
            StringBuilder builder = new StringBuilder();
            builder.Append(this.GetType().ToString());
            builder.Append(Name);

            return builder.ToString().GetHashCode();
        }

        #endregion
    }
}
